<!DOCTYPE html>
<html lang="zh_CN">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	
	<script type="text/javascript">
		/**
		 * 本地存储类
		 * @param preId    本地存储数据库前缀
		 * @param timeSign 时间戳与存储数据之间的拼接符
		 */
		var BaseLocalStorage = function(preId, timeSign) {
			// 定义本地存储数据库前缀
			this.preId = preId;
			// 定义时间戳与存储数据之间的拼接符
			this.timeSign = timeSign || '|-|';
		}
		// 本地存储类圆形方法
		BaseLocalStorage.prototype = {
			// 操作状态
			status: {
				SUCCESS: 0,		// 成功
				FAILURE: 1,		// 失败
				OVERFLOW: 2,	// 溢出
				TIMEOUT: 3		// 过期
			},
			// 保存本地存储链接
			storage: localStorage || window.localStorage,
			// 获取本地存储数据库数据真实字段
			getKey: function(key) {
				return this.preId + key;
			},
			// 添加/修改数据
			set: function(key, value, callback, time) {
					// 默认操作状态时成功
				var status = this.status.SUCCESS,
					// 获取真实字段
					key = this.getKey(key);
				try {
					// 获取时间戳
					time = new Date(time).getTime() || time.getTime();
				} catch(e) {
					// 默认时间：一个月
					time = new Date().getTime() + 1000 * 60 * 60 * 24 * 31;
				}
				try {
					// 向数据库添加数据
					this.storage.setItem(key, time + this.timeSign + value);
				} catch(e) {
					// 溢出，返回溢出状态
					status = this.status.OVERFLOW;
				}
				callback && callback.call(this, status, key, value);
			},
			// 获取数据
			get: function(key, callback) {
				var status = this.status.SUCCESS,	// 默认操作状态时成功
					key = this.getKey(key),		// 获取
					value = null,				// 默认值为空
					timeSignLen = this.timeSign.length,	// 时间戳与存储数据之间的拼接符长度
					that = this,// 缓存当前对象
					index,		// 时间戳与存储数据之间的拼接符长度
					time,		// 时间
					result;		// 最终获取的数据
				try {
					// 获取字段对应的数据字符串
					value = that.storage.getItem(key);
				} catch(e) {
					// 获取失败则返回失败状态，数据结果为null
					result = {
						status: that.status.FAILURE,
						value: null
					};
					callback && callback.call(this, result.status, result.value);
					return result;
				}
				// 如果成功获取数据字符串
				if (value) {
					// 获取拼接符位置
					index = value.indexOf(that.timeSign);
					// 获取时间戳
					time = +value.slice(0, index);
					// 如果已过期
					if (new Date(time).getTime() > new Date().getTime() || time == 0) {
						// 获取数据
						value = value.slice(index + timeSignLen);
					} else {
						// 过期则结果为null
						value = null;
						// 设置状态为过期状态
						status = that.status.TIMEOUT;
						// 删除该字段
						that.remove(key);
					}
				} else {
					// 为获取到数据字符串,状态为失败
					status = that.status.FAILURE;
				}
				// 设置结果
				result = {
					status: status,
					value: value
				};
				// 执行回调函数
				callback && callback.call(this, result.status, result.value);
				// 返回结果
				return result;
			},
			// 删除数据
			remove: function(key, callback) {
					// 设置默认状态为失败
				var status = this.status.FAILURE,
					// 获取实际key
					key = this.getKey(key),
					// 设置默认数据结果为null
					value = null;
				try {
					value = this.storage.getItem(key);
				} catch(e) {}
				// 如果数据存在
				if (value) {
					try {
						this.storage.removeItem(key);
						status = this.status.SUCCESS;
					} catch(e) {}
				}
				// 执行回调
				callback && callback.call(this, status, status > 0 ? null : 
					value.slice(value.indexOf(this.timeSign) + this.timeSign.length));
			}
		}

		// 测试
		var LS = new BaseLocalStorage('LS__');

		LS.set('a', 'xiao ming', function() {
			console.log('set', arguments);
		});
		LS.get('a', function() {
			console.log('get', arguments);
		});
		LS.remove('a', function() {
			console.log('remove', arguments);
		});
		LS.remove('a', function() {
			console.log('remove', arguments);
		});
		LS.get('a', function() {
			console.log('get', arguments);
		});
	</script>
</body>
</html>